package com.changge.common.storage.template.impl;

import com.changge.common.storage.config.properties.LocalProperties;
import com.changge.common.storage.exception.StorageErrorCode;
import com.changge.common.storage.template.AbstractFileUploadStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * 本地文件上传策略
 *
 * @author zhangrongkang
 * @since 2023/12/13
 */
@Slf4j
@Service("localFileUploadStrategy")
public class LocalFileUploadStrategy extends AbstractFileUploadStrategy {

    @Autowired
    private LocalProperties localProperties;

    /**
     * 上传文件
     *
     * @param file     文件数据
     * @param classify 文件分类
     * @param fileName 文件名称
     */
    @Override
    protected void upload(MultipartFile file, String classify, String fileName) {
        String filePath = classify + fileName;
        // 创建文件目录
        try {
            Path directory = Paths.get(localProperties.getPath() + classify);
            // 判断当前文件目录是否存在，不存在则创建
            if (Files.notExists(directory)) {
                // 文件存储目录
                Files.createDirectory(directory);
            }
            // 转存当前文件
            file.transferTo(new File(filePath));
        } catch (Exception e) {
            log.error("本地文件上传失败: {}", e.getMessage());
            throw StorageErrorCode.FILE_UPLOAD_EXCEPTION.exception();
        }
    }

    /**
     * 获取文件访问路径
     *
     * @param filePath 文件路径
     * @return 文件访问路径
     */
    @Override
    protected String getFileAccessUrl(String filePath) {
        return localProperties.getAccessUrl() + filePath;
    }

    /**
     * 获取文件存储路径
     *
     * @param filePath 文件路径
     * @return 文件存储路径
     */
    @Override
    protected String getFileStoragePath(String filePath) {
        return localProperties.getPath() + filePath;
    }

    /**
     * 文件是否存在
     *
     * @param filePath 文件全路径
     * @return true--存在；false--不存在
     */
    @Override
    protected Boolean isExist(String filePath) {
        return new File(localProperties.getPath() + filePath).exists();
    }

    /**
     * 批量删除文件
     *
     * @param filePath 文件存储路径集合
     * @return 是否删除成功
     */
    @Override
    protected Boolean delete(List<String> filePath) {
        // 文件删除结果
        int result = 0;
        // 遍历文件路径集合
        for (String path : filePath) {
            try {
                File file = new File(path);
                if (file.exists() && file.delete()) {
                    result++;
                }
            } catch (Exception e) {
                log.error("本地文件删除失败: {}", e.getMessage());
                throw StorageErrorCode.FILE_DELETE_ERROR.exception();
            }
        }
        // 删除成功数量与集合大小相同则认为删除成功
        return result == filePath.size();
    }
}
